home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 November: Tool Chest / Dev.CD Nov 96 TC / Dev.CD Nov 96 TC.toast / Sample Code / Snippets / Sound / SndPlayDoubleBuffer / _source / MungeBuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-06  |  7.2 KB  |  233 lines  |  [TEXT/CWIE]

  1. /*
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    Routines demonstrating how to manipulate buffers of WAVE data to get them to play correctly.
  5. **
  6. **    by Mark Cookson, Apple Developer Technical Support
  7. **
  8. **    File:    MungeBuffer.c
  9. **
  10. **    Copyright ©1996 Apple Computer, Inc.
  11. **    All rights reserved.
  12. **
  13. **    You may incorporate this sample code into your applications without
  14. **    restriction, though the sample code has been provided "AS IS" and the
  15. **    responsibility for its operation is 100% yours.  However, what you are
  16. **    not permitted to do is to redistribute the source as "Apple Sample
  17. **    Code" after having made changes. If you're going to re-distribute the
  18. **    source, we require that you make it clear in the source that the code
  19. **    was descended from Apple Sample Code, but that you've made changes.
  20. */
  21.  
  22. #include "MungeBuffer.h"
  23.  
  24. /* These three PowerPC assembly routines are used to make a buffer of WAVE sound
  25.    data play as if it was a buffer of a AIFF sound data.
  26.  
  27.    All this really means is that you have to do the endian conversion without
  28.    rearanging the channels if the sound is stereo.
  29.  
  30.    The buffer addressed is passed in register r3 and the count is passed in r4.
  31. */
  32. #ifdef ASM    // Should we use the assembly versions or the C versions of the buffer munging routines?
  33.  
  34. #ifdef powerc
  35.  
  36. asm void EndianMono16BitBuffer (Ptr buf, unsigned long count)
  37. {
  38.         b        test                        // Make sure count is good
  39. more:    subi    r4, r4, 0x04                // Move pointer back 4 bytes to next long
  40.         lwzx    r5, r3, r4                    // Load the long
  41.         rlwinm    r5, r5, 0x10, 0x00, 0x1F    // Rotate long left 16 bits
  42.         stwbrx    r5, r3, r4                    // Write it back out byte reversed
  43. test:    cmpwi    r4, 0x03                    // Are we done yet?
  44.         bgt        more                        // Go back to process more longs
  45.         blr                                    // We're outta here
  46. }
  47.  
  48. asm void EndianStereo8BitBuffer (Ptr buf, unsigned long count)
  49. {
  50.         b        test                        // Make sure count is good
  51. more:    subi    r4, r4, 0x04                // Move pointer back 4 bytes to next long
  52.         lwzx    r5, r3, r4                    // Load the long
  53.         rlwinm    r5, r5, 0x10, 0x00, 0x1F    // Rotate long left 16 bits
  54.         stwx    r5, r3, r4                    // Write it back out (no byte reversing)
  55. test:    cmpwi    r4, 0x03                    // Are we done yet?
  56.         bgt        more                        // Go back to process more longs
  57.         blr                                    // We're outta here
  58. }
  59.  
  60. asm void EndianStereo16BitBuffer (Ptr buf, unsigned long count)
  61. {
  62.         b        test                        // Make sure count is good
  63. more:    subi    r4, r4, 0x04                // Move pointer back 4 bytes to next long
  64.         lwzx    r5, r3, r4                    // Load the long
  65.         stwbrx    r5, r3, r4                    // Write it back out byte reversed
  66. test:    cmpwi    r4, 0x03                    // Are we done yet?
  67.         bgt        more                        // Go back to process more longs
  68.         blr                                    // We're outta here
  69. }
  70.  
  71. /* These are the coresponding 68K versions of the above PowerPC assembly buffer munging routines.
  72.  
  73.    These calls will be called if the target is a 68K based Mac.
  74.  
  75.    The buffer address is passed as the second value (from the top) of the stack, and the count
  76.    is the third value (from the top) of the stack.
  77. */
  78.  
  79. #else //generating 68K
  80.  
  81. asm void EndianMono16BitBuffer (Ptr buf, unsigned long count)
  82. {
  83.         movea.l    0x04(sp), a0                // Put address of buffer in a0
  84.         move.l    0x08(sp), d0                // Put count in d0
  85.         lsr.l    #0x02, d0                    // Divide count by 4
  86.         bra        test                        // Make sure count is good
  87. more:    move.l    (a0), d1                    // Load the long
  88.         ror.w    #0x08, d1                    // Rotate bottom 16 bits
  89.         swap    d1                            // Swap upper and lower words of d1
  90.         ror.w    #0x08, d1                    // Rotate bottom 16 bits (used to be top bits)
  91.         swap    d1                            // Swap upper and lower words of d1
  92.         move.l    d1, (a0)+                    // Store the result
  93. test:    dbra    d0, more                    // Go back and process more longs
  94.         rts                                    // We're outta here
  95. }
  96.  
  97. asm void EndianStereo8BitBuffer (Ptr buf, unsigned long count)
  98. {
  99.         movea.l    0x04(sp), a0                // Put address of buffer in a0
  100.         move.l    0x08(sp), d0                // Put count in d0
  101.         lsr.l    #0x02, d0                    // Divide count by 4
  102.         bra        test                        // Make sure count is good
  103. more:    move.l    (a0), d1                    // Load the long
  104.         swap    d1                            // Swap upper and lower words of d1
  105.         move.l    d1, (a0)+                    // Store the result
  106. test:    dbra    d0, more                    // Go back and process more longs
  107.         rts                                    // We're outta here
  108. }
  109.  
  110. asm void EndianStereo16BitBuffer (Ptr buf, unsigned long count)
  111. {
  112.         movea.l    0x04(sp), a0                // Put address of buffer in a0
  113.         move.l    0x08(sp), d0                // Put count in d0
  114.         lsr.l    #0x02, d0                    // Divide count by 4
  115.         bra        test                        // Make sure count is good
  116. more:    move.l    (a0), d1                    // Load the long
  117.         ror.w    #0x08, d1                    // Rotate bottom 16 bits
  118.         swap    d1                            // Swap upper and lower words of d1
  119.         ror.w    #0x08, d1                    // Rotate bottom 16 bits (used to be top bits)
  120.         move.l    d1, (a0)+                    // Store the result
  121. test:    dbra    d0, more                    // Go back and process more longs
  122.         rts                                    // We're outta here
  123. }
  124.  
  125. #endif
  126.  
  127. #else
  128.  
  129. /* Use C functions instead of assembly functions.
  130.    To use these functions, undefine ASM in MungeBuffer.h.
  131. */
  132.  
  133. void EndianMono16BitBuffer (Ptr buf, unsigned long count)
  134. {
  135.     unsigned long    i;
  136.     unsigned char    tempChar;
  137.  
  138.     for (i = kStartOfBuffer; i < count; i += sizeof (short)) {
  139.         tempChar = (buf)[i];
  140.         (buf)[i] = (buf)[i+1];
  141.         (buf)[i+1] = tempChar;
  142.     }
  143. }
  144.  
  145. void EndianStereo8BitBuffer (Ptr buf, unsigned long count)
  146. {
  147.     unsigned long    i;
  148.     unsigned short    tempShort;
  149.  
  150.     for (i = kStartOfBuffer; i < (count / sizeof (short)); i++) {
  151.         tempShort = ((unsigned short *)buf)[i];
  152.         ((unsigned short *)buf)[i] = ((unsigned short *)buf)[i+1];
  153.         ((unsigned short *)buf)[i+1] = tempShort;
  154.     }
  155. }
  156.  
  157. void EndianStereo16BitBuffer (Ptr buf, unsigned long count)
  158. {
  159.     unsigned long    i;
  160.     unsigned char    tempChar;
  161.  
  162.     for (i = kStartOfBuffer; i < count; i += sizeof (long)) {
  163.         tempChar    = (buf)[i];
  164.         (buf)[i]    = (buf)[i+3];
  165.         (buf)[i+3]    = tempChar;
  166.         tempChar    = (buf)[i+1];
  167.         (buf)[i+1]    = (buf)[i+2];
  168.         (buf)[i+2]    = tempChar;
  169.     }
  170. }
  171.  
  172. #endif
  173.  
  174. void ReverseMono8BitBuffer (const Ptr buf, unsigned long count)
  175. {
  176.     unsigned char    *endBuffer;
  177.     unsigned char    *startBuffer = (unsigned char *)buf;
  178.     unsigned char    saveByte;
  179.     long            i;
  180.  
  181.     endBuffer = ((unsigned char *)buf + count) - 1;
  182.     for (i = (count / (sizeof (char) * kHalfOfBuffer)); i >= kStartOfBuffer; --i) {
  183.         saveByte = *endBuffer;
  184.         *endBuffer-- = *startBuffer;
  185.         *startBuffer++ = saveByte;
  186.     }
  187. }
  188.  
  189. void ReverseStereo8BitBuffer (const Ptr buf, unsigned long count)
  190. {
  191.     unsigned short    *endBuffer;
  192.     unsigned short    *startBuffer = (unsigned short *)buf;
  193.     unsigned short    saveShort;
  194.     long            i;
  195.  
  196.     endBuffer = (unsigned short *)(buf + count) - 1;
  197.     for (i = (count / (sizeof (short) * kHalfOfBuffer)); i >= kStartOfBuffer; --i) {
  198.         saveShort = *endBuffer;
  199.         *endBuffer-- = *startBuffer;
  200.         *startBuffer++ = saveShort;
  201.     }
  202. }
  203.  
  204. void ReverseMono16BitBuffer (const Ptr buf, unsigned long count)
  205. {
  206.     unsigned short    *endBuffer;
  207.     unsigned short    *startBuffer = (unsigned short *)buf;
  208.     unsigned short    saveShort;
  209.     long            i;
  210.  
  211.     endBuffer = (unsigned short *)(buf + count) - 1;
  212.     for (i = (count / (sizeof (short) * kHalfOfBuffer)); i >= kStartOfBuffer; --i) {
  213.         saveShort = *endBuffer;
  214.         *endBuffer-- = *startBuffer;
  215.         *startBuffer++ = saveShort;
  216.     }
  217. }
  218.  
  219. void ReverseStereo16BitBuffer (const Ptr buf, unsigned long count)
  220. {
  221.     unsigned long    *endBuffer;
  222.     unsigned long    *startBuffer = (unsigned long *)buf;
  223.     unsigned long    saveLong;
  224.     long            i;
  225.  
  226.     endBuffer = (unsigned long *)(buf + count) - 1;
  227.     for (i = (count / (sizeof (long) * kHalfOfBuffer)); i >= kStartOfBuffer; --i) {
  228.         saveLong = *endBuffer;
  229.         *endBuffer-- = *startBuffer;
  230.         *startBuffer++ = saveLong;
  231.     }
  232. }
  233.